/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.coach;

import java.util.LinkedList;

import robocup.component.CoachAgent;
import robocup.component.infotypes.AuralInfo;
import robocup.component.infotypes.CoachVisualInfo;
import robocup.component.infotypes.PlayerTypesInfo;

/**
 * The <code>OLCoachTactic</code> is the tactical interface for the (online-) 
 * coach. It implements the InfoReceiver-Interface, and delegates the received
 * information to sub-components. These may subscribe/unsubscribe for certain 
 * info-types (visualInfo, auralInfo and playerTypeInfo), which is remembered
 * in the corresponding lists.<br>
 * Actions (Clang-Messages), which are craeted in the components, are forwarded
 * to the <code>BroadcastCommand</code>, such that the optimal sending time can
 * be determined there (note, that there exist certain restrictions on sending 
 * clang messages). 
 *
 */
public class OLCoachTactic implements InfoReceiver {

	/**
	 * The parent class.
	 */
	private CoachAgent parent;

	/**
	 * The world model of the coach.
	 */
	private CoachWorld cwm;

	/**
	 * The object, which is responsible for determining the optimal sending 
	 * time for clang-messages.
	 */
	private BroadcastCommand bc;

	/**
	 * The list of subscribed receiver-components for visual information.
	 */
	private LinkedList<InfoReceiver> visualInfo = new LinkedList<InfoReceiver>();

	/**
	 * The list of subscribed receiver-components for aural information.
	 */
	private LinkedList<InfoReceiver> auralInfo = new LinkedList<InfoReceiver>();

	/**
	 * The list of subscribed receiver-components for playerType information.
	 */
	private LinkedList<InfoReceiver> ptypeInfo = new LinkedList<InfoReceiver>();

	/**
	 * The Constructor of the Tactic-Object of the Coach. Creates references to
	 * the CoachWorld, and instantiates all analyzers together with their
	 * subscriptions.
	 * 
	 * @param parent -
	 *            the agent object
	 */
	public OLCoachTactic(CoachAgent parent) {

		super();
		this.parent = parent;

		this.cwm = parent.getCoachWorld();
		this.bc = new BroadcastCommand(this);
		visualInfo.add(bc);
		auralInfo.add(bc);

		PlayerTypeAnalyzer pta = new PlayerTypeAnalyzer(this);
		auralInfo.add(pta);
		ptypeInfo.add(pta);

	}

	/**
	 * Notifies all subscribed visual info-receivers.
	 * 
	 * @param info - the latest coach-visual info
	 */
	public void receivedVisualInfo(CoachVisualInfo info) {
		for (InfoReceiver ir : visualInfo) {
			ir.receivedVisualInfo(info);
		}
	}

	/**
	 * Notifies all subscribed aural info-receivers.
	 * 
	 * @param info - the latest aural info
	 */
	public void receivedAuralInfo(AuralInfo info) {
		for (InfoReceiver ir : auralInfo) {
			ir.receivedAuralInfo(info);
		}
	}

	/**
	 * Notifies all subscribed playerType info-receivers.
	 * 
	 * @param info - the latest playerType info
	 */
	public void receivedPlayerTypeInf(PlayerTypesInfo info) {
		for (InfoReceiver ir : ptypeInfo) {
			ir.receivedPlayerTypeInf(info);
		}
	}

	/**
	 * This method removes an InfoReceiver Object from 
	 * the visual info-receiver List
	 * 
	 * @param InfoReceiver - the component, which should be
	 * removed
	 */
	public void removeFromVisualList(InfoReceiver ir) {
		visualInfo.remove(ir);
	}

	/**
	 * This Method removes an InfoReceiver Object from 
	 * the aural info-receiver List
	 * 
	 * @param InfoReceiver - the component, which should be
	 * removed
	 */
	public void removeFromAuralList(InfoReceiver ir) {
		auralInfo.remove(ir);
	}

	/**
	 * This Method removes an InfoReceiver Object from 
	 * the playerType info-receiver List
	 * 
	 * @param InfoReceiver - the component, which should be
	 * removed
	 */
	public void removeFromPtypeList(InfoReceiver ir) {
		ptypeInfo.remove(ir);
	}

	/**
	 * Forwards a freeform message (a string) to the <code>BroadcastCommand
	 * </code>, where the optimal sending time is determined.
	 * 
	 * @param String - the message, which should be sent
	 */
	public void sendFreeform(String str) {
		this.bc.appendFreeform(str);
	}

	/**
	 * Sends a certain string directly to the server (via the send-
	 * method of the CoachAgent). The string should be valid clang-syntax.
	 * 
	 * @param str - the message to send
	 */
	public void sendDirect(String str) {
		this.parent.sendActions(str);
	}

	/**
	 * This Method returns the CoachWorld
	 * 
	 * @return CoachWorld
	 */
	public CoachWorld getCoachWorld() {
		return cwm;
	}

}
